package com.kc.common.utils;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import org.springframework.web.client.RestTemplate;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.Temporal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Component
public class CommonUtils {
    //private final Logger logger = LoggerFactory.getLogger(CommonUtils.class);
    /**
     * 生成随机码
     *
     * @param n        要生成的位数
     * @param isNumber 是否为数字1数字，0非纯数字
     * @return
     */
    public static String getCode(int n, int isNumber) {
        String string = "0123456789";
        if (isNumber == 0) {
            string = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";//保存数字0-9 和 大小写字母
        }
        char[] ch = new char[n];
        for (int i = 0; i < n; i++) {
            Random random = new Random();
            int index = random.nextInt(string.length());
            ch[i] = string.charAt(index);
        }
        String result = String.valueOf(ch);
        System.out.println(result);
        return result;
    }

    /**
     * 正则校验手机号码
     *
     * @param phone 要校验的手机号
     * @return
     */
    public static boolean checkPhone(String phone) {
        String regex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9])|(19[0,5-9]))\\d{8}$";
        if (phone.length() != 11) {
            return false;
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (isMatch) {
                return true;
            } else {
                return false;
            }
        }
    }

    /**
     * 根据手机号码获取用户昵称
     *
     * @param mobile 手机号码
     * @return
     */
    public static String getNickNameByMobile(String mobile) {
        return mobile.substring(0, 3) + "****" + mobile.substring(7);
    }

    /**
     * 获取 md5串
     *
     * @param uid
     * @return
     */
    public static String getToken(Integer uid) {
        String str = uid + (new Date()).toString();
        String md5Str = DigestUtils.md5DigestAsHex(str.getBytes());
        return md5Str;
    }

    /**
     * 对字符串MD5加密
     *
     * @param str
     * @return
     */
    public static String stringToMd5(String str) {
        String md5Str = DigestUtils.md5DigestAsHex(str.getBytes());
        return md5Str;
    }



    /**
     * json字符串转string list
     *
     * @param str
     * @return
     */
    public static List<String> jsonStringToListString(String str) {
        List<Object> strObject = JSONArray.parseArray(str);
        List<String> strList = strObject.stream().map(e -> e.toString()).collect(Collectors.toList());
        return strList;
    }

    /**
     * json字符串转string list
     *
     * @param str
     * @return
     */
    public static List<String> stringToList(String str) {
        //return Arrays.asList(str.split(","));
        if(StringUtils.isEmpty(str)){
            return null;
        }
        String[] arr = StringUtils.split(str,",");
        return Arrays.asList(arr);
    }

    /**
     * 获取评论时间，几秒前，几分钟前等
     * @param date
     * @return
     */
    public static String getTime(Date date) {
        Date currTime = DateUtil.date();;
        Long cha = DateUtil.between(currTime,date,DateUnit.SECOND);
        Integer minuteSecond = 60;
        if (cha < 60) {
            return cha + "秒前";
        } else if (cha < minuteSecond * 60) {
            return (int) (cha / 60) + "分钟前";
        }else if (cha < minuteSecond * 60 * 24) {
            return (int) (cha / 60 / 24) + "小时前";
        }else if (cha < minuteSecond * 60 * 24 * 7) {
            return (int) (cha/3600/24) + "天前";
        }
        return DateUtil.format(date, "yyyy-MM-dd HH:mm:ss");
    }




    /**
     * 字符串拆分成List
     *
     * @param str   原字符串
     * @param regex 拆分标识
     * @return
     */
    public static List<String> stringToStringList(String str, String regex) {
        if (str == null || str.equals("")) {
            return null;
        }
        List<String> strList = new ArrayList<>();
        String[] strArr = str.split(regex);
        Arrays.stream(strArr).map(e -> strList.add(e)).collect(Collectors.toList());
        return strList;
    }

    /**
     * @param str   原字符串
     * @param regex 拆分标识
     * @return
     */
    public static List<Integer> stringToIntegerList(String str, String regex) {
        if (str == null || str.equals("")) {
            return null;
        }
        List<Integer> strList = new ArrayList<>();
        String[] strArr = str.split(regex);
        Arrays.stream(strArr).map(e -> strList.add(Integer.parseInt(e))).collect(Collectors.toList());
        return strList;
    }

    /**
     * 格式化金额
     *
     * @param money
     * @return
     */
    public static String formatMoney(double money) {
        if (money <= 0.0) {
            return "0.0";
        }
        DecimalFormat myFormat = new DecimalFormat();
        myFormat.setGroupingSize(3);
        String output = myFormat.format(money);
        return output;
    }

    /**
     * 单位米距离数字转换成距离
     *
     * @param distance
     * @return
     */
    public static String getDistance(String distance) {
        double dis = Double.parseDouble(distance);
        if(dis == 0){
            return "最近";
        }
        return (int) dis + "km";
//        if (dis < 1000) {
//            return (int) dis + "m";
//        }
//        return ((int) (dis / 10)) / 100 + "km";
    }

    /**
     * 单位米距离数字转换成距离
     *
     * @param distance
     * @return
     */
    public static String getDistanceInfo(String distance) {
        double dis = Double.parseDouble(distance);
        if(dis == 0){
            return "距离最近";
        }
        return "距离" + (int) dis + "km";
    }

    /**
     * 获取当前日期到第二天0晨的秒数
     *
     * @return
     */
    public static int getTomorrowSeconds() {
        Date currentTime = new Date();
        //从一个 Instant和区域ID获得 LocalDateTime实例
        LocalDateTime localDateTime = LocalDateTime.ofInstant(currentTime.toInstant(), ZoneId.systemDefault());
        //获取第第二天零点时刻的实例
        LocalDateTime toromorrowTime = LocalDateTime.ofInstant(currentTime.toInstant(), ZoneId.systemDefault())
                .plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        //ChronoUnit日期枚举类,between方法计算两个时间对象之间的时间量
        long seconds = ChronoUnit.SECONDS.between(localDateTime, toromorrowTime);
        return (int) seconds;
    }

    /**
     * 获取当前日期
     */
    public static String getCurrentDate() {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(calendar.getTime());
    }



    /**
     * OSS获取图片宽高
     * @param fileUrl
     * @return
     */
    public static Map<String,Integer> getImgWidthAndHeight(String fileUrl){
        @Data
        class ImgSize{
            private Map<String,Integer> ImageHeight;
            private Map<String,Integer> ImageWidth;
        }
        Map<String,Integer> map = new HashMap<>();
        if(fileUrl.equals("")){
            map.put("width",0);
            map.put("height",0);
            return map;
        }
        RestTemplate restTemplate = new RestTemplate();
        String[] images = StringUtils.split(fileUrl,"?");
        if(images.length <= 1) {
            fileUrl = fileUrl + "?x-oss-process=image/info";
        }else{
            fileUrl = fileUrl + "&x-oss-process=image/info";
        }

        try {
            ResponseEntity<String> forEntity = restTemplate.getForEntity(fileUrl,String.class);
            ImgSize imgSize = JSONObject.parseObject(forEntity.getBody(), new TypeReference<ImgSize>() {
            });
            map.put("width",imgSize.getImageWidth().get("value"));
            map.put("height",imgSize.getImageHeight().get("value"));
        }catch (Exception e){
            map.put("width",0);
            map.put("height",0);
        }
        return map;
    }

    /**
     * 获取订单号
     *
     * @return
     */
    public synchronized static String getOrderSn() {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String current = LocalDateTime.now().format(dtf);
        String prefix = "KC";
        return prefix + current + getRandomString(6);
    }

    /**
     * 获取订单号
     *
     * @return
     */
    public synchronized static String getOrderSn(String prefix) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
        String current = LocalDateTime.now().format(dtf);
        return prefix + current + getRandomString(6);
    }

    /**
     * 获取图片的base64编码
     * @param remark
     * @return
     */
    public static String encodeImgageToBase64(String remark) {

        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            //创建url
            URL url = new URL(remark);
            byte[] by = new byte[1024];
            //创建连接
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            //将内容读取到内存中
            int len = -1;
            while((len = is.read(by))!=-1){
                data.write(by,0,len);
            }
            //关闭流
            is.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
        Base64Encoder encoder = new Base64Encoder();
        return  encoder.encode(data.toByteArray());

    }

    /**
     * 获取两个日期月数差
     * @param dateOne
     * @param dateTwo
     * @return
     */
    public static Long getMonthDiff(String dateOne,String dateTwo){
        dateOne = dateOne.substring(0,10);
        dateTwo = dateTwo.substring(0,10);
        if("0000-00-00".equals(dateOne) || "0000-00-00".equals(dateTwo)){
            return 0l;
        }
        Temporal temporalOne = LocalDate.parse(dateOne.trim());
        Temporal temporalTwo = LocalDate.parse(dateTwo.trim());
        Long num = ChronoUnit.MONTHS.between(temporalOne,temporalTwo);
        return num <= 0 ? 1 : num;
    }
    /**
     * 获取两个日期天数差
     * @param dateOne
     * @param dateTwo
     * @return
     */
    public static Long getDayDiff(String dateOne,String dateTwo){
        if(StringUtils.isEmpty(dateOne) || StringUtils.isEmpty(dateTwo)){
            return 0l;
        }

        dateOne = dateOne.substring(0,10);
        dateTwo = dateTwo.substring(0,10);
        if("0000-00-00".equals(dateOne) || "0000-00-00".equals(dateTwo)){
            return 0l;
        }
        Temporal temporalOne = LocalDate.parse(dateOne.trim());
        Temporal temporalTwo = LocalDate.parse(dateTwo.trim());
        Long num = ChronoUnit.DAYS.between(temporalOne,temporalTwo);
        return num <= 0 ? 1 : num;
    }
    /**
     * 获取指定年后的日期
     * @param yearNum
     * @return
     */
    public static String getEndDateByYear(Integer yearNum){
//        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
//        Date date = new Date();
//        Calendar c = Calendar.getInstance();
//        c.setTime(date);//设置起时间
//        c.add(Calendar.YEAR, yearNum);
//        return fmt.format(c.getTime());

        return DateUtil.offset(DateUtil.parse(DateUtil.now()), DateField.DAY_OF_MONTH, yearNum).toString();
    }
    /**
     * 获取指定月后的日期
     * @param monthNum
     * @return
     */
    public static String getEndDateByMonth(Integer monthNum){
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);//设置起时间
        c.add(Calendar.MONTH, monthNum);//增加一个月
        return fmt.format(c.getTime());
    }

    /**
     * 获取指定天后的日期
     * @param dayNum
     * @return
     */
    public static String getEndDateByDay(Integer dayNum){
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(date);//设置起时间
        c.add(Calendar.DATE, dayNum);
        return fmt.format(c.getTime());
    }

    /**
     * 获取当前日期到指定日期的秒数
     * @param endDate
     * @return
     */
    public static Long getBetweenSecond(String endDate){
        Date currDate = DateUtil.date();
        Date date2 = DateUtil.parse(endDate);
        long betweenSecond = DateUtil.between(currDate, date2, DateUnit.SECOND);
        return betweenSecond;
    }

    /**
     * 获取两个日期的毫秒数
     * @param dateOne
     * @param dateTwo
     * @return
     */
    public static Long getBetweenSecond(String dateOne,String dateTwo){
        if("0000-00-00".equals(dateOne) || "0000-00-00".equals(dateTwo)){
            return 0l;
        }
        Date startDate = DateUtil.parse(dateOne);
        Date endDate = DateUtil.parse(dateTwo);
        long betweenSecond = DateUtil.betweenMs(startDate, endDate);
        return betweenSecond;
    }

    /**
     * 获取日期对应星期
     * @param date
     * @return
     */
    public static String getWeek(Date date){
        String[] weekDays = { "周日", "周一", "周二", "周三", "周四", "周五", "周六" };
        return weekDays[DateUtil.dayOfWeek(date)-1];
    }

    public static String getRandomString(int length) {
        StringBuffer sb = new StringBuffer();
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                sb.append(new Random().nextInt(10));
            }
            return sb.toString();
        }
        return null;
    }

    /**
     * 获取商品订单是否归属平台
     * @param goodsType
     * @return
     */
    public static Integer getGoodsOrderPlatform(Integer goodsType){
        if(goodsType < 0 || goodsType.equals(5)){
            return 0;
        }
        return 1;
    }


}
